package bio_nio_aio.bio.com_Demo.wechatroom;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;


public class ClientFrame extends Frame {

	private static final long serialVersionUID = 1L;

	private TextField textFieldContent = new TextField();
	private TextArea textAreaContent = new TextArea();
	private Socket socket = null;
	private OutputStream out = null;
	private DataOutputStream dos = null;
	private InputStream in = null;
	private DataInputStream dis = null;
	private boolean flag = false;

	/**
	 * 功能：启动客户端程序
	 *
	 * @param args
	 */
	public static void main(String[] args) {
		new ClientFrame().init();
	}

	/**
	 * 功能：对窗口进行初始化
	 */
	private void init() {
		this.setSize(300, 300);
		setLocation(250, 150);
		setVisible(true);
		setTitle("聊天室");

		// 添加控件
		this.add(textAreaContent);
		this.add(textFieldContent, BorderLayout.SOUTH);
		textAreaContent.setFocusable(false);
		pack();

		// 关闭事件
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.out.println("用户试图关闭窗口");
				//关闭的时候断开连接
				disconnect();
				//结束程序
				System.exit(0);
			}
		});

		// textFieldContent 添加回车事件
		textFieldContent.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// 点击 enter 键发送消息
				onClickEnter();
			}
		});

		// 建立连接(这里是与服务器进行连接，主要是对参数进行初始化)
		connect();
		// 读取服务器发送过来的消息
		new Thread(new ReceiveMessage()).start();
	}

	private class ReceiveMessage implements Runnable {
		@Override
		public void run() {
			//如果抛出异常就将 flag 的值置为 false
			flag = true;
			try {
				while (flag) {
					String message = dis.readUTF();
					//将接受的到信息添加到text中信息的尾部
					textAreaContent.append(message + "\n");
				}
			} catch (EOFException e) {
				flag = false;
				System.out.println("客户端已关闭");
				e.printStackTrace();
			} catch (SocketException e) {
				flag = false;
				System.out.println("客户端已关闭");
				e.printStackTrace();
			} catch (IOException e) {
				flag = false;
				System.out.println("接受消息失败");
				e.printStackTrace();
			}
		}
	}

	/**
	 * 功能：当点击回车时出发的事件
	 */
	private void onClickEnter() {
		//获取输入框的信息
		String message = textFieldContent.getText().trim();
		if (message != null && !message.equals("")) {
			String time = new SimpleDateFormat("h:m:s").format(new Date());
			textAreaContent.append(time + "\n" + message + "\n");
			textFieldContent.setText("");
			//向服务器发送
			sendMessageToServer(message);
		}
	}

	/**
	 * 功能：给服务器发送消息
	 *
	 * @param message
	 */
	private void sendMessageToServer(String message) {
		try {
			//以与机器无关方式使用 UTF-8 修改版编码将一个字符串写入基础输出流。
			dos.writeUTF(message);
			dos.flush();
		} catch (IOException e) {
			System.out.println("发送消息失败");
			e.printStackTrace();
		}
	}

	/**
	 * 功能：申请socket链接 (在建立连接的时候就会进行一些初始化的操作)
	 */
	private void connect() {
		try {
			//192.168.43.171
			socket = new Socket("127.0.0.1", 8888);
			//发送消息的流对象
			out = socket.getOutputStream();
			dos = new DataOutputStream(out);
			//接受消息的流对象
			in = socket.getInputStream();
			dis = new DataInputStream(in);
		} catch (UnknownHostException e) {
			System.out.println("申请链接失败");
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("申请链接失败");
			e.printStackTrace();
		}
	}

	/**
	 * 功能：关闭流和链接
	 */
	private void disconnect() {
		flag = false;
		if (dos != null) {
			try {
				dos.close();
			} catch (IOException e) {
				System.out.println("dos关闭失败");
				e.printStackTrace();
			}
		}
		if (out != null) {
			try {
				out.close();
			} catch (IOException e) {
				System.out.println("dos关闭失败");
				e.printStackTrace();
			}
		}
		if (socket != null) {
			try {
				socket.close();
			} catch (IOException e) {
				System.out.println("socket关闭失败");
				e.printStackTrace();
			}
		}
	}
}